﻿
using CommunicationProtocol.dto.command;
using CommunicationProtocol.filters;
using monoClient.filter;
using monoClient.renderer;
using monoClient.utils;
using server.filters;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CommunicationProtocol.dto.command.client;
using CommandExecutor = monoClient.renderer.CommandExecutor;
namespace monoClient.communication
{
    internal class SyncServerGamingDataTask
    {

        Socket client;
        string ip;
        int port;


        List<NetFilter> inband;

        List<NetFilter> outband;

        ConcurrentDictionary<CommandExecutor,object> commandExecutors;
        private string v1;
        private int v2;
        private CancellationToken token;

        public SyncServerGamingDataTask(
            string ip,
            int port, 
            ConcurrentDictionary<CommandExecutor,object> commandExecutors,
            CancellationToken token)
        {
            this.ip = ip;
            this.port = port;
            this.token = token;

            this.commandExecutors = commandExecutors;

            inband =new List<NetFilter>() { 
                new DecodeFrameFilter(),
                new ServerCommandParser(commandExecutors),
                //new PackageRuoteFactory(form),
            };


        }

       

        public async Task  run()
        {
            while (!token.IsCancellationRequested) {
                // 安全的退出本线程
                try
                {
                    client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);


                    Task connectServerTask = client.ConnectAsync(ip, port);


                    await connectServerTask;

                    Console.WriteLine("成功连接服务器");

                    outband = new List<NetFilter>() {

                        new CommandEncoder(),
                        new EncodeFrameFilter(),
                        new SocketSenderFilter(client)
                    };

                    OutBandHolder.set(  outband);

                    // 请求可选择的植物列表
                    OutBandHolder.send(new RequestBuyablePlantList());
            
                    // 请求地图上已经种植的植物
                    OutBandHolder.send(new RequestAllDynamicPlant());
                    
                    while (true)
                    {
                        receivingData();
                    }

                }
                catch (SocketException ex)
                {
                    Console.WriteLine("连接服务器异常"+ex.ToString());
                    client.Close();
                    Thread.Sleep(1000);
                    Console.WriteLine("尝试重新连接服务器");
                }
            }
        }

        private void receivingData() {
            if (!client.Poll(1000, SelectMode.SelectRead))
            {
                return;
            }

            byte[] buffer = new byte[client.Available];
            client.Receive(buffer);

            new InvocationChain(inband).invoke(buffer);
        }
    }
}
